#include"Common.h"
#include"Sem.hpp"
#include"Mutex.hpp"

template<class T>
class RingQueue
{
public:
    RingQueue(int num = 10)
        :_v(num)
        ,_capacity(num)
        ,_c_index(0)
        ,_p_index(0)
        ,_space_sem(num)
        ,_data_sem(0)
    {}
    void push(const T& in)
    {
        _space_sem.p();//生产者申请空间资源
        _p_mtx.lock();//为生产者加锁
        _v[_p_index++] = in;
        _p_index %= _capacity;
        _p_mtx.unlock();//为生产者解锁
        _data_sem.v();//数据资源多了个
    }
    void pop(T* out)
    {
        _data_sem.p();//消费者申请数据资源
        _c_mtx.lock();//为消费者加锁
        *out = _v[_c_index++];
        _c_index %= _capacity;
        _c_mtx.unlock();//为消费者解锁
        _space_sem.v();//空间资源多了个
    }
    ~RingQueue()
    {}
private:
    std::vector<T> _v;
    int _capacity;
    int _c_index;
    int _p_index;
    Sem _space_sem;
    Sem _data_sem;
    Mutex _c_mtx;
    Mutex _p_mtx;
};